package com.example.d6_homework.homework07.thread;

import com.example.d6_homework.homework07.classloader.HotClassLoader;

import java.io.File;
import java.lang.reflect.Method;

/**
 * ExecRunnable 实现了 Runnable 接口,用于在指定的包中查找并执行符合特定条件的类的方法。
 * 它通过 HotClassLoader 加载类,并执行那些无参数且返回类型为 void 的方法。
 */
public class ExecRunnable implements Runnable {
    // hotLoaderSourceFilePackage 存储了需要热加载的文件包名。
    private final String hotLoaderSourceFilePackage;
    // classLoader 用于加载指定包中的类。
    private final HotClassLoader classLoader;

    /**
     * 构造函数,初始化 ExecRunnable 实例。
     *
     * @param hotLoaderSourceFilePackage 指定需要热加载的文件包名。
     */
    public ExecRunnable(String hotLoaderSourceFilePackage) {
        this.hotLoaderSourceFilePackage = hotLoaderSourceFilePackage;
        this.classLoader = new HotClassLoader(hotLoaderSourceFilePackage);
    }

    /**
     * run 方法是线程的入口点。
     * 它不断检查指定包中的类文件,并加载执行符合特定条件的方法。
     */
    @Override
    public void run() {
        while (true) {
            // 构造类文件的目录路径。
            String sourceFileDirectory = "src/" + hotLoaderSourceFilePackage.replace(".", "/") + "/";
            File directory = new File(sourceFileDirectory);
            File[] files = directory.listFiles();
            for (File file : files) {
                // 仅处理 .class 文件。
                if (file.getName().endsWith(".class")) {
                    // 从文件名中提取类名。
                    String className = file.getName().replace(".class", "");
                    try {
                        // 加载类并创建实例。
                        Class<?> clazz = classLoader.loadClass(hotLoaderSourceFilePackage + "." + className);
                        Object instance = clazz.getDeclaredConstructor().newInstance();
                        // 遍历类的方法,找到无参数且返回类型为 void 的方法并执行。
                        for (Method method : clazz.getDeclaredMethods()) {
                            if (method.getParameterCount() == 0 && method.getReturnType() == void.class) {
                                method.setAccessible(true);
                                method.invoke(instance);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            try {
                Thread.sleep(1000); // 线程休眠1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
